package com.ebelter.seneo.models;


import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Message;
import android.text.TextUtils;

import com.ebelter.btcomlib.common.Constants;
import com.ebelter.btcomlib.models.beans.ScaleUser;
import com.ebelter.btcomlib.models.bluetooth.base.BlueManager;
import com.ebelter.btcomlib.models.bluetooth.base.BlueScan;
import com.ebelter.btcomlib.models.bluetooth.bean.ProductStyle;
import com.ebelter.btcomlib.models.bluetooth.interfaces.IBlueStationListener;
import com.ebelter.btcomlib.models.bluetooth.interfaces.IConnectStationCallback;
import com.ebelter.btcomlib.models.bluetooth.interfaces.IScanCallback;
import com.ebelter.btcomlib.models.bluetooth.products.scale.ScaleManager;
import com.ebelter.btcomlib.models.bluetooth.products.scale.bean.ScaleMeasureResult;
import com.ebelter.btcomlib.models.bluetooth.products.scale.interfaces.IScaleMeasureCallback;
import com.ebelter.btcomlib.models.db.products.seneo.SeneoUserCurrentMeasureRecord;
import com.ebelter.btcomlib.models.db.products.seneo.SeneoUserinfos;
import com.ebelter.btcomlib.models.https.NetUtils;
import com.ebelter.btcomlib.models.https.interfaces.HttpResponse;
import com.ebelter.btcomlib.utils.BaseHandle;
import com.ebelter.btcomlib.utils.NumUtils;
import com.ebelter.btcomlib.utils.TimeUtils;
import com.ebelter.btcomlib.utils.ToastUtil;
import com.ebelter.btcomlib.utils.UserSpUtil;
import com.ebelter.btcomlib.utils.ViewUtils;
import com.ebelter.btcomlib.utils.log.LogUtils;
import com.ebelter.seneo.R;
import com.ebelter.seneo.beans.HostoryListData;
import com.ebelter.seneo.contants.IUserContant;
import com.ebelter.seneo.interfaces.SeneoBTI;
import com.ebelter.seneo.ui.fragments.main.Dash_Fragment;
import com.ebelter.seneo.ui.fragments.main.Goal_Fragment;
import com.ebelter.seneo.ui.fragments.main.Info_Fragment;
import com.ebelter.seneo.ui.fragments.main.Set_Fragment;
import com.ebelter.seneo.ui.fragments.main.Trend_Fragment;
import com.ebelter.seneo.utils.SeneoUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import static com.ebelter.seneo.utils.SeneoUtils.userid2btid;

public class SeneoBTManager extends BaseHandle{


    private static final String TAG = "SeneoBTManager";


    public static long currentUseUserId;

    private Context context;


    private ScaleManager mScaleManager;

    private long currentUserId;
    private SeneoUserinfos currentUserinfos;


    //唯一连接的地址 默认是扫描周围蓝牙 蓝牙名字符合就连接
    private String mustConnectBlueAddress;

    //蓝牙扫描器
    private BlueScan mBlueScan;


    public void setCurrentUserId(long currentUserId) {
        this.currentUserId = currentUserId;
        currentUseUserId=currentUserId;
        currentUserinfos = SeneoDbUtils.getUserinfos(currentUserId);


        if (currentUserinfos==null){
            String tip = "setCurrentUserId---发生逻辑性的错误,未找到此用户id的信息 currentUserId = "+currentUserId;
            LogUtils.i2(TAG,tip);
        }else {
            LogUtils.i2(TAG,"setCurrentUserId()---currentUserId = " + currentUserId+"找到用户信息 准备下发了用户信息");
            sendUserInfo2Scale();
        }

        //这里更新当前用户的数据4
        SeneoUtils.updateCurrentInfoDiaplay(TAG);

        SeneoUtils.sendCommonEventBus(TAG, Trend_Fragment.TAG, IUserContant.ICMDS.REQUEST_TREND_DATA,"切换用户成功，重新请求趋势数据");

        getUserMeasureDataFrom(currentUserId);


    }

    //
    private void getUserMeasureDataFrom(final long currentUserId) {
        if (!NetUtils.available()){
            return;
        }
        final long host_id = SeneoDbUtils.getHostId();

        Map<String,Serializable> paramMap=new HashMap<>();
        paramMap.put("userId", currentUserId);
        paramMap.put("startIndex", 0);
        paramMap.put("pageSize", 1);
        SeneoNet.getIntance().getsHostoryListData(this, paramMap, new HttpResponse<HostoryListData>() {
            @Override
            public void result(boolean isRequestSuccess, String requestDes, HostoryListData hostoryListData,String s) {
                LogUtils.i(TAG,TAG+"---获取最新的测量数据 s ="+s);
                if (isRequestSuccess){
                    LogUtils.i(TAG,"获取到此用户最新的一条用户测量信息="+hostoryListData.toString());
                    if (hostoryListData.resultCode==0){
                        //2018-06-19 12:15:12

                            if (hostoryListData.getResultData()!=null&&hostoryListData.getResultData().getData()!=null){
                                if (hostoryListData.getResultData().getData().size()>0){
                                    HostoryListData.ResultDataBean.DataBean dataBean = hostoryListData.getResultData().getData().get(0);
                                    //获取此用户下的最新的一条数据
                                    SeneoUserCurrentMeasureRecord currentMeasureRecord = SeneoDbUtils.getSeneoUserCurrentMeasureRecord(host_id,currentUserId);
                                    boolean isSave;
                                    if (currentMeasureRecord==null){
                                        LogUtils.i(TAG,TAG+"---获取最新的测量数据 找不到当前用户的测量数据");
                                        currentMeasureRecord = new SeneoUserCurrentMeasureRecord();
                                        currentMeasureRecord.host_id=host_id;
                                        currentMeasureRecord.user_id=currentUserId;
                                        isSave=true;
                                    }else {
                                        long currentMeasureRecordTime = TimeUtils.parseFormatter1Time(currentMeasureRecord.measureTime).getTime();
                                        long netTime = TimeUtils.parseFormatter1Time(dataBean.getTestDate()).getTime();
                                        //对比网络上的时间和本地的测量时间
                                        LogUtils.i(TAG,TAG+"---获取最新的测量数据 currentMeasureRecordTime="+currentMeasureRecordTime+"---netTime="+netTime);
                                        if (currentMeasureRecordTime<netTime){
                                            isSave=false;
                                            LogUtils.i(TAG,TAG+"---获取最新的测量数据--本地时间小于网络数据的时间 准备进行更新网络数据");
                                        }else {
                                            LogUtils.i(TAG,TAG+"---获取最新的测量数据--本地时间大于网络数据的时间 不进行更新网络数据");
                                            SeneoUtils.sendCommonEventBus(TAG,Dash_Fragment.TAG, IUserContant.ICMDS.DISPLAY_DASH_USER_DATA,"显示用户的最后一次测量数据");
                                            return;
                                        }
                                    }

                                    currentMeasureRecord.weight = NumUtils.numBaoLiuWei1((float) dataBean.getWeight());
                                    currentMeasureRecord.measureTime = dataBean.getTestDate();

                                    currentMeasureRecord.fat=NumUtils.numBaoLiuWei1((float) dataBean.getAdiposeRate());
                                    currentMeasureRecord.bmi=NumUtils.numBaoLiuWei1((float) dataBean.getBmi());
                                    currentMeasureRecord.bmr=NumUtils.numBaoLiuWei1((float) dataBean.getBmr());
                                    currentMeasureRecord.visceralFat=NumUtils.numBaoLiuWei1((float) dataBean.getVisceralFat());
                                    currentMeasureRecord.muscleVolume=NumUtils.numBaoLiuWei1((float) dataBean.getMuscleQuantity());
                                    currentMeasureRecord.boneVolume=NumUtils.numBaoLiuWei1((float) dataBean.getBoneMass());
                                    currentMeasureRecord.protein=NumUtils.numBaoLiuWei1((float) dataBean.getProtein());
                                    currentMeasureRecord.waterRate=NumUtils.numBaoLiuWei1((float) dataBean.getMoisture());
                                    currentMeasureRecord.skeletalMuscle=NumUtils.numBaoLiuWei1((float) dataBean.getBoneMineralContent());
                                    currentMeasureRecord.bodyAge=NumUtils.numBaoLiuWei1((float) dataBean.getPhysicalAge());
                                    currentMeasureRecord.bodyScore=NumUtils.numBaoLiuWei1((float) dataBean.getBodySocre());

                                    currentMeasureRecord.weightControl=NumUtils.numBaoLiuWei1(dataBean.getWeightControl());

                                    if (isSave){
                                        currentMeasureRecord.save();
                                        LogUtils.i(TAG,TAG+"---获取最新的测量数据 新增");
                                    }else {
                                        currentMeasureRecord.update();
                                        LogUtils.i(TAG,TAG+"---获取最新的测量数据 更新");
                                    }

                                    LogUtils.i(TAG,TAG+"---获取最新的测量数据 发消息出去");
                                    SeneoUtils.updateCurrentInfoDiaplay(TAG);

                                    SeneoUtils.sendCommonEventBus(TAG,Dash_Fragment.TAG, IUserContant.ICMDS.DISPLAY_DASH_USER_DATA,"显示用户的最后一次测量数据");

                                }else {
                                    SeneoUtils.sendCommonEventBus(TAG,Dash_Fragment.TAG, IUserContant.ICMDS.DISPLAY_DASH_USER_DATA_NULL,"显示用户的最后一次测量数据为空指令");
                                }
                            }
                    }
                }
            }
        });

    }

    public long getCurrentUserId() {
        return this.currentUserId;
    }

    public SeneoUserinfos getCurrentUserinfos() {
        return this.currentUserinfos;
    }
    private boolean isWorkFlag;



    public void restartSendUserInfo(int resistance,float weight){
        ScaleUser.getUser().setImpedance(resistance);
        ScaleUser.getUser().setWeight(weight);
        if (mScaleManager!=null){
            mScaleManager.sendUserInfo(ScaleUser.getUser());
        }

    }

    public SeneoBTManager(Context context) {
        super(context);

        this.context = context;
        mBlueScan=new BlueScan(context);


        mScaleManager=new ScaleManager(context,200);

        mScaleManager.setmIMeasureResultCallback(new IScaleMeasureCallback() {
            @Override
            public void onReceiveMeasureResult(ScaleMeasureResult result) {

                LogUtils.i2(TAG,"----A--onReceiveMeasureResult--"+result);
                result=SeneoUtils.checkScaleMeasureResult18old(result);

                //接收到测量信息 第一步 //发送一个ack
                sendMesureDataACK();

                //接收到测量信息 第二步 //下发一次用户信息
                restartSendUserInfo((int) result.getResistance(),result.weight);

                if (mSeneoBTI!=null)mSeneoBTI.onReceiveMeasureResult(result);





            }

            @Override
            public void onReceivedynamicMeasureResult(ScaleMeasureResult result) {
                if (mSeneoBTI!=null)mSeneoBTI.onReceivedynamicMeasureResult(result);
            }

            @Override
            public void onWeightOverLoad() {
                if (mSeneoBTI!=null)mSeneoBTI.onWeightOverLoad();
            }

            @Override
            public void onReceiveHistoryRecord(ScaleMeasureResult result) {
                result=SeneoUtils.checkScaleMeasureResult18old(result);
                //接收到历史测量信息
                sendHistoryDataACK();//发送一个ack
                if (mSeneoBTI!=null)mSeneoBTI.onReceiveHistoryRecord(result);

            }

            @Override
            public void onFatMeasureError(int type) {
                if (mSeneoBTI!=null)mSeneoBTI.onFatMeasureError(type);
            }

            @Override
            public void onHistoryDownloadDone() {
                if (mSeneoBTI!=null)mSeneoBTI.onHistoryDownloadDone();
            }

            @Override
            public void unitChange(String unit) {
                if (mSeneoBTI!=null)mSeneoBTI.unitChange(unit);
            }

            @Override
            public void onLowPower() {
                if (mSeneoBTI!=null)mSeneoBTI.onLowPower();
            }

            @Override
            public void setUserInfoSuccess() {
                if (mSeneoBTI!=null)mSeneoBTI.setUserInfoSuccess();

                long clearusertime=  UserSpUtil.readLong(IUserContant.IUser.clearUserTime);
                if (System.currentTimeMillis()-clearusertime<2000){
                    //说明2秒内用户有清空用户的指令操作
                    UserSpUtil.writeLong(IUserContant.IUser.clearUserTime,System.currentTimeMillis()-3000);//为了下一次回来的时候不用调用此方法了
                    sendUserInfo2Scale();//重新下发一下用户信息
                }
                LogUtils.i(TAG,"下发用户信息成功");
            }

            @Override
            public void receiveTime(long time) {
                if (mSeneoBTI!=null)mSeneoBTI.receiveTime(time);
                LogUtils.i(TAG,"接收到秤的时钟信息 time = "+ TimeUtils.formatTime1(time));
                //第二步 下发用户信息
                sendUserInfo2Scale();

            }

            @Override
            public void onScaleWake() {
                if (mSeneoBTI!=null)mSeneoBTI.onScaleWake();

                LogUtils.i(TAG,"----秤亮屏 准备下发时钟信息");
                //第一步 连接成功的时候下发时钟信息
                syncSystemClock();
            }

            @Override
            public void onScaleSleep() {
                LogUtils.i(TAG,"----秤息屏");
                if (mSeneoBTI!=null)mSeneoBTI.onScaleSleep();

                //在息屏的时候获取离线数据
                getHistoryDataRequest(ScaleUser.getUser().getBtId());
            }

            @Override
            public void dealScaleResponse(int cmd, int position) {
                //ota升级的时候会用到
            }
        });

        mScaleManager.setBlueConnectStationCallback(new IConnectStationCallback() {
            @Override
            public void onConnected(ProductStyle productStyle, BluetoothDevice device) {
                if (mSeneoBTI!=null)mSeneoBTI.onConnected(device);
                LogUtils.i(TAG,"体脂秤连接成功 准备下发时钟信息");

                ScaleUser.currentConnectScaleBlueName=device.getName();

            }

            @Override
            public void onConnecting(ProductStyle productStyle, BluetoothDevice device) {
                if (mSeneoBTI!=null)mSeneoBTI.onConnecting(device);
            }

            @Override
            public void onDisConnected(ProductStyle productStyle) {
                if (mSeneoBTI!=null)mSeneoBTI.onDisConnected();
            }
        });

        BlueManager.getInstance().addBluetoothStationListener(mIBlueStationListener);
    }

    private IBlueStationListener mIBlueStationListener = new IBlueStationListener() {
        @Override
        public void STATE_OFF() {

        }

        @Override
        public void STATE_TURNING_OFF() {

        }

        @Override
        public void STATE_ON() {

            removeMessages(WHAT_AOTUCHECK);
            sendEmptyMessageDelayed(WHAT_AOTUCHECK, 2000);
        }

        @Override
        public void STATE_TURNING_ON() {

        }
    };

    private void sendUserInfo2Scale() {
        if (mScaleManager!=null){
            SeneoUserinfos userinfos = currentUserinfos;
            if (userinfos==null){
                LogUtils.i(TAG,"sendUserInfo2Scale---发生逻辑性的错误,未找到此用户id的信息 currentUserId = "+currentUserId);
                return;
            }
            ScaleUser scaleUser = ScaleUser.getUser();

            String btId = ScaleUser.toBtId(userid2btid(currentUserId));
            scaleUser.setBtId(btId);//1


            int heigh = userinfos.height;
            int sex =userinfos.sex;////0男1女
            String birthday = userinfos.birthday;//格式永远是1901-06-13
            int athlete=userinfos.athlete;//0运动员 1普通
            int impedance = userinfos.impedance;

            float weight = userinfos.currentWeight;
            if (weight<=0){
                weight=50;
            }
            scaleUser.setWeight(weight);//2
            scaleUser.setHeight(heigh);//3
            scaleUser.setSex(sex);//4

            int year = SeneoUtils.getBirthdayIntValue(birthday,0,1991);
            int age = SeneoUtils.getAgeByBirthday(year);
            scaleUser.setAge(age);//5
            scaleUser.setRoleType(athlete);//6

            if (impedance<200||impedance>1500){//7
                impedance=500;
            }
            scaleUser.setImpedance(impedance);

            LogUtils.i(TAG,"下发用户信息 currentUserId="+currentUserId+"--btId="+btId+"--height="+heigh+"--sex="+sex+
            "--birthday="+birthday+"--age="+age+"--athlete(0普通1运动员)="+athlete+"--impedance="+impedance+"--weight="+weight);

            if (isConnect()){
                LogUtils.i2(TAG,"执行了下发了用户信息的指令");
                mScaleManager.sendUserInfo(scaleUser);
            }

        }
    }


    public void startWork(){
        isWorkFlag=true;
        autoCheck();
    }


    private long nextAutoCheckTime = 3500;
    private void autoCheck() {
        boolean isConnect=isConnect();
        if (isConnect){
            //说明没有连接着，下一次检测的时候快一点来
            nextAutoCheckTime = 3500;
        }else {
            //说明有连接着，下一次检测的时候可以慢一点来
            nextAutoCheckTime = 7000;
        }
        sendEmptyMessageDelayed(WHAT_AOTUCHECK,nextAutoCheckTime);//7秒钟后自动继续检测

        if (mSeneoBTI==null)return;

        //01
        String address = SeneoUtils.getBondAddress();
        if (TextUtils.isEmpty(address)){
            //说明没有绑定设备 弹出框提醒用户去绑定设备
            mSeneoBTI.showBondDialog();
            if (isConnect){disconnect();}
            return;
        }


        //02
        SeneoUserinfos userinfos =SeneoDbUtils.getUserinfos(currentUserId);
        if (userinfos==null){
            String error = "autoCheck---发生逻辑性的错误,未找到此用户id的信息 currentUserId = "+currentUserId;
            LogUtils.i(TAG,error);
            mSeneoBTI.error(error);
            return;
        }


        int heigh = userinfos.height;
        int sex =userinfos.sex;////0男1女
        String birthday = userinfos.birthday;//格式永远是1901-06-13
        int athlete=userinfos.athlete;//0运动员 1普通

        if (heigh<=0||sex<0||TextUtils.isEmpty(birthday)||athlete<0){
            //说明此用户信息不完全
            mSeneoBTI.addInfoDialog(currentUserId,userinfos.nickName);
            return;
        }
        //说明此用户信息是完整的


        //03
       // boolean isConnect = isConnect();
        String connectAddress = getConnectAddress();
        if (!TextUtils.isEmpty(connectAddress)&&TextUtils.equals(connectAddress,address)){
            LogUtils.i(TAG,"autoCheck--体脂秤秤连接着 autoCheck 此次结束 reture");
        }else {
            LogUtils.i(TAG,"autoCheck--检测到体脂秤未连接或者地址不一样 准备开始连接 address = "+address);
            scanBlueDevices(address);
        }
    }

    //扫描蓝牙设备
    private void scanBlueDevices(String address) {

        this.mustConnectBlueAddress=address;
        if (mBlueScan != null) {
            mBlueScan.stopScanBluetoothDevices();//先停止扫描
        }
        removeMessages(WHAT_START_SCAN);
        sendEmptyMessageDelayed(WHAT_START_SCAN,1000);//停止一秒后再去扫描的意思

    }

    private String getConnectAddress() {
        if (mScaleManager!=null){
            return mScaleManager.getConnectAddress();
        }
        return null;
    }

    public boolean isConnect() {
        if (mScaleManager!=null){
            return mScaleManager.isConnect();
        }
        return false;
    }


    //同步时钟
    private void syncSystemClock() {
        if (mScaleManager!=null){
            mScaleManager.syncSystemClock();
        }
    }


    public void stopWork(){
        disconnect();

        removeMessages(WHAT_AOTUCHECK);

        isWorkFlag=false;
    }

    private void disconnect(){
        if (mScaleManager!=null){
            mScaleManager.disConnect();
        }
    }


    private static final int WHAT_AOTUCHECK = 5;
    private static final int WHAT_START_SCAN = 6;
    private static final int WHAT_RESTART_SCAN = 7;
    @Override
    public void handleMsg(Message msg) {
        super.handleMsg(msg);

        switch (msg.what){
            case WHAT_AOTUCHECK:
                autoCheck();
                break;
            case WHAT_START_SCAN:
                if (mBlueScan!=null){
                    LogUtils.i(TAG, "---收到开始扫描的指令");
                    mBlueScan.startScanBluetoothDevices(mScanCallback);//开始扫描
                }
                break;
        }

    }
    /**
     * 当前需要连接的设备
     */
    private BluetoothDevice device;
    //扫描回调器
    private IScanCallback mScanCallback = new IScanCallback() {
        @Override
        public void beforeScan() {
            LogUtils.i(TAG, "---beforeScan---");
            device = null;
        }

        @Override
        public void scanOneDevice(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            post(new Runnable() {
                @Override
                public void run() {
                    recordScanDevice(device);
                }
            });

        }

        @Override
        public void overScan() {
            LogUtils.i(TAG, "---扫描结束---");
            if (device == null) {
                //说明没有扫描成功 需要重新扫描
                LogUtils.i(TAG, "---扫描结束 device = null 未扫描到任何设备");
//                stopScan();
//                removeMessages(WHAT_START_SCAN);
//                sendEmptyMessageDelayed(WHAT_START_SCAN, 1000);//这里不delay是因为开始扫描那里会停留一秒了
            }
        }
    };

    private void stopScan() {
        if (mBlueScan != null) {
            mBlueScan.stopScanBluetoothDevices();
        }
    }


    private void recordScanDevice(BluetoothDevice device) {
        // if (device == null) {return;}
        String name = device.getName();
        String address = device.getAddress();


        if (TextUtils.isEmpty(name)||TextUtils.isEmpty(address)){
           // LogUtils.i(TAG, "扫描到设备的设备地址为空 reture");
            return;
        }
        LogUtils.i(TAG, "扫描到设备--Name = " + name + "---Addrss = " + address);

        if (!TextUtils.equals(mustConnectBlueAddress,address)){
            LogUtils.i(TAG, "扫描到设备的设备地址不是 mustConnectBlueAddress reture");
            //扫描的到的蓝牙地址不符合
            return;
        }
        LogUtils.i(TAG, "--找到了需要连接的蓝牙设备------Name = " + name + "---Addrss = " + address + "---准备连接---");
        this.device = device;

        stopScan();//退出扫描
        connectBluetooth(device);//开始连接设备

    }

    private void connectBluetooth(BluetoothDevice device) {
        if(mScaleManager!=null){
            mScaleManager.connectDevice(device);
        }
    }

    public void exit(){
        if (mBlueScan!=null){
            mBlueScan.stopScanBluetoothDevices();
            mBlueScan=null;
        }
        stopWork();
        BlueManager.getInstance().removeBluetoothStationListener(mIBlueStationListener);
        if (mScaleManager!=null){
            mScaleManager.exit();
            mScaleManager=null;
        }

    }


    private SeneoBTI mSeneoBTI;

    public void setmSeneoBTI(SeneoBTI mSeneoBTI) {
        this.mSeneoBTI = mSeneoBTI;
    }

    //获取历史数据
    private void getHistoryDataRequest(String uid){
        if (mScaleManager!=null){
            mScaleManager.sendGetHistoryDataRequest(uid);
        }
    }

    private void sendHistoryDataACK() {
        if (mScaleManager!=null){
            mScaleManager.sendGetHistoryDataACK();
        }

    }

    private void sendMesureDataACK() {
        if (mScaleManager!=null){
            mScaleManager.sendMesureDataACK();
        }
    }

    public void restartCheck() {
        removeMessages(WHAT_AOTUCHECK);
        sendEmptyMessage(WHAT_AOTUCHECK);
    }


    //清除所有用户信息
    public void clearAllUserInfo() {
        if (mScaleManager!=null){
            mScaleManager.deleteAllUserInfo();
        }
    }


}
